package com.wf.classRoomTest.customer;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.LinkedList;

class BoundedBuffer {
    public static void main(String[] args) {
        final BoundedBuffer buffer = new BoundedBuffer(5); // 设置缓冲区容量为5

        // 创建生产者线程
        Thread producerThread = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    buffer.put(i); // 生产者不断地向缓冲区放入元素
                    Thread.sleep(1000); // 模拟生产过程
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 创建消费者线程
        Thread consumerThread = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    buffer.take(); // 消费者不断地从缓冲区取出元素
                    Thread.sleep(1500); // 模拟消费过程
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 启动生产者和消费者线程
        producerThread.start();
        consumerThread.start();
    }
    private final LinkedList<Integer> buffer = new LinkedList<>();
    private final int capacity;
    private final Lock lock = new ReentrantLock();
    private final Condition notFull  = lock.newCondition(); // 缓冲区未满的条件
    private final Condition notEmpty = lock.newCondition(); // 缓冲区非空的条件

    BoundedBuffer(int capacity) {
        this.capacity = capacity;
    }

    void put(int value) throws InterruptedException {

            lock.lock();
            try {

                if (buffer.size() == capacity) {
                    System.out.println("缓冲区已满，生产者等待...");
                    notFull.await(); // 如果缓冲区满，生产者等待
                }
                buffer.addLast(value);
                System.out.println("生产者生产了一个元素，值为：" + value);
                notEmpty.signal(); // 唤醒一个可能等待的消费者

            } finally {

                lock.unlock();

            }

    }

    int take() throws InterruptedException {

            lock.lock();
            try {
                if (buffer.isEmpty()) {
                    System.out.println("缓冲区已空，消费者等待...");
                    notEmpty.await(); // 如果缓冲区空，消费者等待
                }
                int value = buffer.removeFirst();
                System.out.println("消费者消费了一个元素，值为：" + value);
                notFull.signal(); // 唤醒一个可能等待的生产者

                return value;
            } finally {
                lock.unlock();
            }

    }
}
